#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#include <unistd.h>
#include <signal.h>

int System(char* cmd) {
	pid_t pid;
	int status;

	struct sigaction ignore, saveintr, savequit;
	sigset_t chldmask, savemask;

	if (cmd == NULL)
		return -1;

	ignore.sa_handler = SIG_IGN;
	sigemptyset(&ignore.sa_mask);
	ignore.sa_flags = 0;
	if (sigaction(SIGINT, &ignore, &saveintr) < 0) {
		printf("sigaction error\n");
		return -1;
	}

	if (sigaction(SIGQUIT, &ignore, &savequit) < 0) {
		printf("sigaction error\n");
		return -1;
	}
	sigemptyset(&chldmask);
	sigaddset(&chldmask, SIGCHLD);
	if (sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0) {
		printf("sigprocmask error\n");
		return -1;
	}

	if ((pid=fork()) < 0) {
		status = -1;
	}
	else if (pid == 0) {
		sigaction(SIGINT, &saveintr, NULL);
		sigaction(SIGQUIT, &savequit, NULL);
		sigprocmask(SIG_SETMASK, &savemask, NULL);

		execl("/bin/sh", "sh", "-c", cmd, (char*)0);
		exit(127);
	} else {
		while (waitpid(pid, &status, 0) < 0) {
			if (errno != EINTR) {
				status = -1;
				break;
			}
		}
	}

	if (sigaction(SIGINT, &saveintr, NULL) < 0) {
		return -1;
	}
	if (sigaction(SIGQUIT, &savequit, NULL) < 0) {
		return -1;
	}
	if (sigprocmask(SIG_SETMASK, &savemask, NULL) < 0) {
		return -1;
	}

	return status;
}

int main() {
	System("ls -l");
	return 0;
}